package com.company.myfirstjmixproject.screen;

import org.atmosphere.annotation.AnnotationUtil;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Copyright(C) 2023 Cardinal Operations. All rights reserved.
 *
 * @author ZhaoBo (zhaobo@shanshu.ai)
 * @date 2023/3/26 13:49
 */
public class Car {

    private String code;

    private String carType;

    private String name;

    private String dimension0;
    private String dimension1;
    private String dimension2;
    private String dimension3;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getCarType() {
        return carType;
    }

    public void setCarType(String carType) {
        this.carType = carType;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDimension0() {
        return dimension0;
    }

    public void setDimension0(String dimension0) {
        this.dimension0 = dimension0;
    }

    public String getDimension1() {
        return dimension1;
    }

    public void setDimension1(String dimension1) {
        this.dimension1 = dimension1;
    }

    public String getDimension2() {
        return dimension2;
    }

    public void setDimension2(String dimension2) {
        this.dimension2 = dimension2;
    }

    public String getDimension3() {
        return dimension3;
    }

    public void setDimension3(String dimension3) {
        this.dimension3 = dimension3;
    }

    public Car(String code, String carType, String name, String dimension0, String dimension1, String dimension2, String dimension3) {
        this.code = code;
        this.carType = carType;
        this.name = name;
        this.dimension0 = dimension0;
        this.dimension1 = dimension1;
        this.dimension2 = dimension2;
        this.dimension3 = dimension3;
    }

    @Override
    public String toString() {
        return "Car{" +
                "code='" + code + '\'' +
                ", carType='" + carType + '\'' +
                ", name='" + name + '\'' +
                ", dimension0='" + dimension0 + '\'' +
                ", dimension1='" + dimension1 + '\'' +
                ", dimension2='" + dimension2 + '\'' +
                ", dimension3='" + dimension3 + '\'' +
                '}';
    }

    public static void main(String[] args) {

        List<Car> cars = new LinkedList<>();
        cars.add(new Car("C0001", "T1", "C1系列红", null, "FW_001", null, null));
        cars.add(new Car("C0001", "T1", "C1系列白", null, "FW_001", null, null));
        cars.add(new Car("C0002", "T2", "C2系列蓝", "item002", "FW_002", null, null));
        cars.add(new Car("C0002", "T2", "C2系列金", "item002", "FW_003", null, null));

        String methodName = "getCode";


//        Map<String, List<Car>> collect = cars.stream().collect(Collectors.groupingBy(c -> getGroupKey(c, Car.class, new Integer[]{0, 1})));
//        System.out.println(collect);

        List<Car> lowerMeasureData = getLowerMeasureData(cars, Car.class, 0);
        System.out.println(lowerMeasureData);

    }

    private static String getGroupKey(Car c) {
        return c.getCode() + c.getName();
    }


    private static <T> List<T> getLowerMeasureData(List<T> details, Class<T> tClass, int index) {
        Field[] declaredFields = tClass.getDeclaredFields();
        String fieldName = "dimension" + index;
        Field field = Arrays.stream(declaredFields)
                .filter(it -> Objects.equals(fieldName, it.getName()))
                .findFirst().orElseThrow(() -> new RuntimeException("reflect can not find field"));
        field.setAccessible(true);

        return details.stream().filter(d -> {
            try {
                return Objects.nonNull(field.get(d));
            } catch (IllegalAccessException e) {
                throw new RuntimeException("reflect can not find field");
            }
        }).toList();
    }

    private static <T> String getGroupKey(T detail, Class<T> clazz, Integer[] dimensionIndexes) {
        Field[] declaredFields = clazz.getDeclaredFields();
        StringBuilder groupByKey = new StringBuilder();

        for (int i = 0; i < dimensionIndexes.length; i++) {
            String fieldName = "dimension" + dimensionIndexes[i];
            Field field = Arrays.stream(declaredFields)
                    .filter(it -> Objects.equals(fieldName, it.getName()))
                    .findFirst().orElseThrow(() -> new RuntimeException("reflect can not find field"));
            field.setAccessible(true);
            try {
                Object dimension = field.get(detail);
                if (Objects.nonNull(dimension)) {
                    if (i < dimensionIndexes.length - 1) {
                        groupByKey.append(dimension).append("_");
                    } else {
                        groupByKey.append(dimension);
                    }
                }
            } catch (IllegalAccessException e) {
                throw new RuntimeException("reflect error on measure value transfer", e);
            }

        }
        return groupByKey.toString();
    }
}
